package com.cqq.auth.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cqq.auth.constant.AuthMessage;
import com.cqq.auth.dao.PermissionDao;
import com.cqq.auth.dao.RoleDao;
import com.cqq.auth.dao.domain.Role;
import com.cqq.auth.dao.query.RoleQuery;
import com.cqq.auth.service.RoleService;
import com.cqq.auth.service.bean.RoleBean;
import com.cqq.auth.service.bean.RoleQueryBean;
import com.cqq.auth.service.exception.RoleServiceException;
import com.cqq.common.core.base.BaseService;
import com.cqq.common.core.bean.PageInfoBean;
import com.cqq.common.core.constant.CommonMessage;
import com.cqq.common.core.util.BeanUtil;

@Service("roleService")
public class RoleServiceImpl extends BaseService implements RoleService {

	private static final Logger log = LoggerFactory.getLogger(RoleServiceImpl.class);
	
	@Autowired
	private RoleDao roleDao;

	@Autowired
	private PermissionDao permissionDao;
	
	
	public void addRole(RoleBean role) throws RoleServiceException {
		log.debug("addRole ...");
		if(role==null || StringUtils.isBlank(role.getCode())
				|| StringUtils.isBlank(role.getName())
				|| role.getSystemCode()==null
				|| role.getSystemCode().length==0
				|| role.getType()==null){
			throw super.buildException(new RoleServiceException(CommonMessage.COMMON_PARAM_EMPTY));
		}
		
		Role r=this.roleDao.queryByCode(role.getCode(), role.getSystemCode());
		if(r != null){
			throw super.buildException(new RoleServiceException(AuthMessage.ROLE_CODE_DUPLICATE));
		}
		r=this.roleDao.queryByName(role.getName(), role.getSystemCode());
		if(r != null){
			throw super.buildException(new RoleServiceException(AuthMessage.ROLE_NAME_DUPLICATE));
		}
		if(role.getCreaterId()==null){
			role.setCreaterId(0);
		}
		r=new Role();
		BeanUtil.copy(role, r);
		this.roleDao.add(r);
		role.setId(r.getId());
		log.debug("addRole ok! {}",role);
	}

	
	public void deleteRole(Integer id) throws RoleServiceException {
		log.debug("deleteRole ...");
		if(id==null){
			throw super.buildException(new RoleServiceException(CommonMessage.COMMON_PARAM_EMPTY));
		}
		Role role=this.roleDao.queryById(id);
		if(role==null){
			throw super.buildException(new RoleServiceException(AuthMessage.ROLE_NOT_EXIST));
		}
		this.roleDao.delete(id);
		log.debug("deleteRole ok! id:{}",id);
	}

	
	public void updateRole(RoleBean role) throws RoleServiceException {
		log.debug("updateRole ...");
		if(role==null || role.getId()==null
				|| StringUtils.isBlank(role.getCode())
				|| StringUtils.isBlank(role.getName())
				|| role.getSystemCode()==null
				|| role.getSystemCode().length==0
				|| role.getType()==null){
			throw super.buildException(new RoleServiceException(CommonMessage.COMMON_PARAM_EMPTY));
		}
		
		Role r=this.roleDao.queryByCode(role.getCode(), role.getSystemCode());
		if(r != null && !r.getId().equals(role.getId())){
			throw super.buildException(new RoleServiceException(AuthMessage.ROLE_CODE_DUPLICATE));
		}
		r=this.roleDao.queryByName(role.getName(), role.getSystemCode());
		if(r != null && !r.getId().equals(role.getId())){
			throw super.buildException(new RoleServiceException(AuthMessage.ROLE_NAME_DUPLICATE));
		}
		
		r=new Role();
		BeanUtil.copy(role, r);
		this.roleDao.update(r);
		log.debug("updateRole ok! {}",role);
	}

	
	public RoleBean findRole(Integer id) {
		if(id==null){
			return null;
		}
		Role role=this.roleDao.queryById(id);
		if(role==null){
			return null;
		}
		RoleBean bean=new RoleBean();
		BeanUtil.copy(role, bean);
		return bean;
	}

	
	public List<RoleBean> listAllRole(String systemCode) {
		if(StringUtils.isBlank(systemCode)){
			return null;
		}
		List<Role> roles=this.roleDao.queryAllBySystem(new String[]{systemCode});
		List<RoleBean> beans=BeanUtil.copyList(roles, RoleBean.class);
		return beans;
	}

	
	public List<RoleBean> listRoleByUserId(Integer id, String systemCode) {
		if(id==null || StringUtils.isBlank(systemCode)){
			return null;
		}
		List<Role> roles=this.roleDao.queryByUserId(id, new String[]{systemCode});
		List<RoleBean> beans=BeanUtil.copyList(roles, RoleBean.class);
		return beans;
	}

	
	public List<RoleBean> listRoleByUsername(String username,
			String systemCode) {
		if(StringUtils.isBlank(username) || StringUtils.isBlank(systemCode)){
			return null;
		}
		List<Role> roles=this.roleDao.queryByUsername(username, new String[]{systemCode});
		List<RoleBean> beans=BeanUtil.copyList(roles, RoleBean.class);
		return beans;
	}

	
	public void updateRolePermissions(Integer roleId, Integer[] permIds,
			String systemCode) throws RoleServiceException {
		log.debug("updateRolePermissions ...");
		if(roleId==null || permIds==null || permIds.length==0
				|| StringUtils.isBlank(systemCode)){
			throw super.buildException(new RoleServiceException(CommonMessage.COMMON_PARAM_EMPTY));
		}
		Role role=this.roleDao.queryById(roleId);
		if(role==null){
			throw super.buildException(new RoleServiceException(AuthMessage.ROLE_NOT_EXIST));
		}
		Integer[] newPermIds=permIds;
		if(role.getPermIds()!=null && role.getPermIds().length>0){
			List<Integer> ids=this.permissionDao.queryIdsBySystem(systemCode);
			Set<Integer> idSet=new HashSet<Integer>();
			idSet.addAll(ids);
			List<Integer> newIds=new ArrayList<Integer>();
			for(Integer id:role.getPermIds()){
				if(!idSet.contains(id)){
					newIds.add(id);
				}
			}
			for(Integer id:permIds){
				if(!idSet.contains(id)){
					throw super.buildException(new RoleServiceException(AuthMessage.PERM_NOT_EXIST));
				}
				newIds.add(id);
			}
			newPermIds=(Integer[]) newIds.toArray();
		}
		this.roleDao.updatePermIds(roleId, newPermIds);
		log.debug("updateRolePermissions ok! roleId:{}, permIds:{}, systemCode:{}", roleId, permIds, systemCode);
	}

	
	public PageInfoBean<RoleBean> queryRoleByPage(RoleQueryBean queryBean) {
		log.debug("queryRoleByPage ...");
		if(queryBean==null){
			return null;
		}
		RoleQuery query=new RoleQuery();
		BeanUtil.copy(queryBean, query);
		List<RoleBean> beanList=null;
		Integer count=this.roleDao.queryCount(query);
		if(count>0){
			List<Role> roles=this.roleDao.queryPage(query);
			beanList=BeanUtil.copyList(roles, RoleBean.class);
		}
		PageInfoBean<RoleBean> page=new PageInfoBean<RoleBean>(beanList,count,queryBean.getPageSize(),queryBean.getPageNo());
		log.debug("queryRoleByPage ok! {}",queryBean);
		return page;
	}

	
	public List<RoleBean> listRoleByUserGroupId(Integer userGroupId,
			String systemCode) {
		if(userGroupId==null || StringUtils.isBlank(systemCode)){
			return null;
		}
		List<Role> roles=this.roleDao.queryByUserGroupId(userGroupId, new String[]{systemCode});
		List<RoleBean> beans=BeanUtil.copyList(roles, RoleBean.class);
		return beans;
	}
}
